﻿#pragma once
#include <QObject>
#include "componentbase.h"
#include "component_data.h"

#define component (ComponentManager::GetInstance())

class SystemJournal;
class ComponentManager : public QObject
{
    Q_OBJECT
public:
	ComponentManager(QObject *parent);
	~ComponentManager();
    static ComponentManager* GetInstance();
    bool Init();

	bool InitForSystemSetting();
    bool CheckComponent();
    bool ResetComponent();

    /****************************************************************************
     * 功能: 获取组件
     * 传参: id: 组件类型， loaded: true 表示只获取已经加载的组件， flase表示可以获取插件组件
     * 返回值: 组件指针，获取失败为nullptr
     ****************************************************************************/
    ComponentBase* GetComponent(Component id, bool loaded = false);
    ComponentBase* GetComponentByStr(const QString& str);
    QString GetErrorMsg();

    void RegisterSystemEventCallBake(std::function<void(int)> callbake);

public slots:
    void DealWithComponentSystemEvent(int componet, int Event);
    void DealWithComponentWarningEvent(int componet, const QString& msg);
    void DealWithSystemEvent(int state);    // 系统状态处理
signals:
    void PublishSystemEvent(int Event); // 系统事件信号， 组件可以选择订阅

private:
	void Sleep(int msec);

private:
    std::map<Component, ComponentBase*> m_components;   // 已经加载的组件
    QString m_errmsg;
    SystemJournal* m_writer = nullptr;
    QString m_version;
    std::map<Component, ComponentBase*> m_plugins;   // 插件组件, 未加载到系统

    QList<std::function<void(int)>> m_sytemCall;
};
